/***********************************************************************************************//**
*\n  @file       bus_gpio.cpp
*\n  @brief      gpio 总线地址操作
*\n  @details
*\n -----------------------------------------------------------------------------------
*\n  文件说明：
*\n 	1. gpio 总线地址操作
*\n
*\n -----------------------------------------------------------------------------------
*\n  版本:  	 修改人:       修改日期:        描述:
*\n  V0.01   罗先能        2021.05.10    创建
*\n
***************************************************************************************************/


/**************************************************************************************************
* 头文件
***************************************************************************************************/
#include <iostream>
#include "bus_gpio.hpp"

#undef  DEBUG_LEVEL
#define DEBUG_LEVEL  2   // 定义debug级别 (0 ~ 5)
#include "vdebug.h"

using namespace std;

/**************************************************************************************************
* 宏定义、结构定义
***************************************************************************************************/


/**************************************************************************************************
* 全局变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有函数声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 全局函数声明、定义
***************************************************************************************************/
TGpioBus::~TGpioBus()
{
	if(NULL != this->pBaseAddress)
	{
		munmap(this->pBaseAddress, this->mAddressSize);
		this->pBaseAddress = NULL;
	}
	if (this->mFd > 0)
	{
		close(this->mFd);
		this->mFd = -1;
	}
	debug_printf("%s->~TGpioBus() \n",this->mName);
}



TGpioBus::TGpioBus(const char name[], long physicalAddress, long size/*=0x1000*/)
{
	mFd = open("/dev/mem",  O_RDWR | O_SYNC);
	if (mFd < 0)
	{
		debug_error("open(/dev/mem) < 0\n");
		return ;
	}
	this->mAddressSize = size;
	this->pBaseAddress = mmap(NULL, this->mAddressSize,
							  PROT_READ | PROT_WRITE, MAP_SHARED,
							  this->mFd, (off_t)physicalAddress);
	if (MAP_FAILED == this->pBaseAddress)
	{
		this->pBaseAddress = NULL;
		debug_error("mmap(%p) < 0\n", (void*)physicalAddress);
		return;
	}
	debug_printf("TGpioBus::TGpioBus(%s,0x%08lx,0x%08lx) \n",mName,physicalAddress,size);
}


int TGpioBus::Write(long address, void *pBuf, long iCnt)
{
	if ((mFd < 0) || (NULL == pBuf) || (iCnt <= 0))
	{
		if (mFd < 0)
			debug_error("mFd < 0 \n");
		if (NULL == pBuf)
			debug_error("NULL == pBuf \n");
		if (iCnt <= 0)
			debug_error("iCnt <= 0 \n");
		return -1;
	}

	// 写寄存器
	RegisterSet(this->pBaseAddress, address, *((long *)pBuf));
	return sizeof(long);
}


int TGpioBus::Read(long address, void *pBuf, long iCnt)
{
	if ((mFd < 0) || (NULL == pBuf) || (iCnt <= 0))
	{
		if (mFd < 0)
			debug_error("mFd < 0 \n");
		if (NULL == pBuf)
			debug_error("NULL == pBuf \n");
		if (iCnt <= 0)
			debug_error("iCnt <= 0 \n");
		return -1;
	}

	// 读寄存器
	*((long *)pBuf) = RegisterGet(this->pBaseAddress, address);
	return sizeof(long);
}



